package com.androway.services;

import java.util.ArrayList;
import java.util.List;

import android.util.Base64;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.reflect.TypeToken;
import com.loopj.android.http.AsyncHttpClient;
import com.loopj.android.http.AsyncHttpResponseHandler;
import com.loopj.android.http.RequestParams;

public class Requester
{
	private static AsyncHttpClient client = new AsyncHttpClient();
	private OnResponseListener listener;
	private static final String DATETIME_FORMAT = "dd-MM-yyyy HH:mm:ss";

	public static interface OnResponseListener
	{
		public void onSuccess(RequestType type, List<?> objects, String service);

		public void onError(RequestType type, String errorMessage);
	}

	public static enum RequestType
	{
		GET, POST, PUT, DELETE
	};

	public Requester()
	{
	}

	public void setListener(OnResponseListener listener)
	{
		this.listener = listener;
	}

	private AsyncHttpResponseHandler getHandler(final RequestType type, final Class<?> clazz, final String service)
	{
		return new AsyncHttpResponseHandler()
		{
			@Override
			public void onSuccess(String message)
			{
				List<Object> objs = null;
				if (type == RequestType.GET)
				{
					Gson gson = new GsonBuilder().setDateFormat(Requester.DATETIME_FORMAT).create();
					if (message.charAt(0) == '[')
					{
						objs = gson.fromJson(message, new TypeToken<List<?>>()
						{
						}.getType());
					}
					else
					{
						objs = new ArrayList<Object>();
						objs.add(gson.fromJson(message, clazz));
					}
					Requester.this.listener.onSuccess(type, objs, service);
				}
				else
					Requester.this.listener.onSuccess(type, null, service);

			}

			@Override
			public void onFailure(Throwable e, String error)
			{
				Requester.this.listener.onError(type, error);
			}
		};
	}

	private void doGet(String url, Class<?> clazz, String service)
	{
		client.get(url, this.getHandler(RequestType.GET, clazz, service));
	}

	private void doPost(String url, Object obj, Class<?> clazz, String service)
	{
		RequestParams params = new RequestParams();
		Gson gson = new Gson();

		params.put("json", gson.toJson(obj));
		client.post(url, params, this.getHandler(RequestType.POST, clazz, service));
	}

	private void doDelete(String url, Class<?> clazz, String service)
	{
		client.delete(url, this.getHandler(RequestType.DELETE, clazz, service));
	}

	private void doPut(String url, Object obj, Class<?> clazz, String service)
	{
		RequestParams params = new RequestParams();
		Gson gson = new Gson();

		params.put("json", gson.toJson(obj));
		client.put(url, params, this.getHandler(RequestType.PUT, clazz, service));
	}

	public void doRequest(String url, RequestType type, Class<?> clazz, String service)
	{
		if (type == RequestType.GET)
			this.doGet(url, clazz, service);
		else if (type == RequestType.DELETE)
			this.doDelete(url, null, service);
	}

	public void setAuthentification(String username, String password)
	{
		String authString = "Basic " + Base64.encodeToString((username + ":" + password).getBytes(), Base64.DEFAULT);
		client.addHeader("Authorization", authString);
	}

	public void doRequest(String url, RequestType type, Object obj, String service)
	{
		if (type == RequestType.POST)
			this.doPost(url, obj, null, service);
		else if (type == RequestType.PUT)
			this.doPut(url, obj, null, service);
	}

}
